package com.imooc.miaosha.config;

import com.imooc.miaosha.pojo.domain.MiaoshaUser;
import com.imooc.miaosha.service.MiaoshaUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    MiaoshaUserService miaoshaUserService;
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        HandlerMethodArgumentResolver userArgumentResolver =
                new HandlerMethodArgumentResolver() {
                    @Override
                    /*
                    * 对带有MiaoshaUser形参(parameter)的方法进行处理，返回true*/
                    public boolean supportsParameter(MethodParameter parameter) {
                        Class<?> clazz = parameter.getParameterType();
                        return clazz==MiaoshaUser.class;
                    }

                    @Override
                    /*
                    * 当supportParameter()返回true时调用该方法，此时应该返回的是该Parameter的实参(argument)
                    * */
                    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
                        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
                        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);

                        //下面是从cookie中或请求参数中携带的token字段中获取token，这是一种很好的方式，因为这样可以支持多设备，
                        //比如移动设备不支持cookie那么就可以通过携带token字段验证登录状态
                        String paramToken = request.getParameter(MiaoshaUserService.COOKIE_NAME_TOKEN);
                        String cookieToken = getCookie(request);
                        if (!StringUtils.hasLength(paramToken)&&!StringUtils.hasLength(cookieToken))
                            return null;
                        String token = StringUtils.hasLength(paramToken) ? paramToken:cookieToken;
                        return miaoshaUserService.getByToken(response, token);
                    }
        };
        resolvers.add(userArgumentResolver);

    }

    /**
     * 遍历request中的所有cookie
     * @param request
     * @return
     */
    private String getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (ObjectUtils.isEmpty(cookies)) return null;
        for(Cookie cookie : cookies){
            if (cookie.getName().equals(MiaoshaUserService.COOKIE_NAME_TOKEN))
                return cookie.getValue();
        }
        return null;
    }
}
